using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.ComponentModel;
using System.Drawing;

using Microsoft.AnalysisServices.AdomdClient;


namespace BILab.Technical.Forms.BI.UI
{
    [ToolboxBitmap(typeof(TreeView))]
    public class MdGridView : DataGridView
    {
        #region fields and properties
        private Color _headerBackground = Color.SteelBlue;
        private Color _headerForeground = Color.White;


        public Color HeaderBackground
        {
            get { return _headerBackground; }
            set { _headerBackground = value; }
        }
       

        public Color HeaderForeground
        {
            get { return _headerForeground; }
            set { _headerForeground = value; }
        }
        #endregion

        #region Complex Grid
        public void DisplayCellSetHierarchy(CellSet  cs)
        {
            int columnPosition;
            int rowPosition;

            OlapInfo olapInfo =  cs.OlapInfo;
            OlapInfoAxis columnAxisInfo = olapInfo.AxesInfo.Axes[0];
            OlapInfoAxis rowAxisInfo = olapInfo.AxesInfo.Axes[1];

            Axis columnAxis =  cs.Axes[0];
            Axis rowAxis =  cs.Axes[1];

            int colOffset = rowAxisInfo.Hierarchies.Count;
            int rowOffset = columnAxisInfo.Hierarchies.Count;


            int numberOfColumns = rowAxisInfo.Hierarchies.Count +  cs.Axes[0].Positions.Count;
            int numberOfRows = columnAxisInfo.Hierarchies.Count +  cs.Axes[1].Positions.Count;

            // 1 - DGV Setup
            this.ColumnCount = numberOfColumns;
            this.RowCount = numberOfRows;
            this.ColumnHeadersVisible = false;
            this.RowHeadersVisible = false;

            this.Columns[colOffset - 1].Frozen = true;
            this.Rows[rowOffset - 1].Frozen = true;

            // 2 - Information Analysis
            Dictionary<int, Headers> rowDict = analyseHeaders(rowAxisInfo, rowAxis);
            Dictionary<int, Headers> colDict = analyseHeaders(columnAxisInfo, columnAxis);

            // Dump for test
            //StringBuilder sb = new StringBuilder();
            //foreach (int key in rowDict.Keys)
            //{
            //    sb = new StringBuilder();
            //    sb.Append(" Key ");
            //    sb.Append(key);

            //    Headers tempHeaders = rowDict[key];

            //    foreach (Header hdr in tempHeaders)
            //    {
            //        sb.Append(" ");
            //        sb.Append(hdr.Caption);
            //        if (hdr.IsNew) { sb.Append(" Is New "); }
            //        else { sb.Append(" is not new "); }
            //    }
            //    Debug.WriteLine(sb.ToString());
            //}

            // 3 - Column Header Presentation
            int columnHierNumber = columnAxisInfo.Hierarchies.Count;
            for (columnPosition = 0; columnPosition < columnAxis.Positions.Count; columnPosition++)
            {
                for (int hierCount = 0; hierCount < columnHierNumber - 1; hierCount++)
                {
                    if (colDict.ContainsKey(columnPosition))
                    {
                        Header header = colDict[columnPosition][hierCount];
                        if (header.IsNew)
                        {
                            this[columnPosition + colOffset, hierCount].Value = header.Caption;
                        }
                    }
                    this[colOffset + columnPosition, hierCount].Style.BackColor =HeaderBackground;
                    this[colOffset + columnPosition, hierCount].Style.ForeColor = HeaderForeground;
                }

                this[colOffset + columnPosition, columnHierNumber - 1].Style.BackColor =HeaderBackground;
                this[colOffset + columnPosition, columnHierNumber - 1].Style.ForeColor = HeaderForeground;
                this[colOffset + columnPosition, columnHierNumber - 1].Value = columnAxis.Positions[columnPosition].Members[columnHierNumber - 1].Caption;
            }


            // 4 - Row Header and Data loading
            int rowHierNumber = rowAxisInfo.Hierarchies.Count;

            for (rowPosition = 0; rowPosition < rowAxis.Positions.Count; rowPosition++)
            {
                // 4.1 - Header drawing if necessary
                for (int hierCount = 0; hierCount < rowHierNumber - 1; hierCount++)
                {
                    if (rowDict.ContainsKey(rowPosition))
                    {
                        if (rowDict[rowPosition][hierCount].IsNew)
                        {
                            this[hierCount, rowPosition + rowOffset].Value = rowAxis.Positions[rowPosition].Members[hierCount].Caption;
                        }
                    }
                    this[hierCount, rowPosition + rowOffset].Style.BackColor =HeaderBackground;
                    this[hierCount, rowPosition + rowOffset].Style.ForeColor = HeaderForeground;
                }

                // 4.2 - Last hiearchy member is systematically  written
                this[rowHierNumber - 1, rowPosition + rowOffset].Style.BackColor =HeaderBackground;
                this[rowHierNumber - 1, rowPosition + rowOffset].Style.ForeColor = HeaderForeground;
                this[rowHierNumber - 1, rowPosition + rowOffset].Value = rowAxis.Positions[rowPosition].Members[rowHierNumber - 1].Caption;


                // 4.3 - Data loading
                for (columnPosition = 0; columnPosition < columnAxis.Positions.Count; columnPosition++)
                {
                    this[columnPosition + colOffset, rowPosition + rowOffset].Value =  cs.Cells[columnPosition, rowPosition].FormattedValue;
                }
            }

            this.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells;

        }

        private Dictionary<int, Headers> analyseHeaders(OlapInfoAxis  axisInfo, Axis  axis)
        {
            Dictionary<int, Headers>  dict = new Dictionary<int, Headers>();
            bool isNew = false;

            Headers previousNewHeaders = new Headers();

            for (int i = 0; i <  axisInfo.Hierarchies.Count; i++)
            {
                Header hdr = new Header();
                hdr.Caption = null;
                hdr.IsNew = true;

                previousNewHeaders.Add(hdr);
            }

            for (int position = 0; position <  axis.Positions.Count; position++)
            {
                // Step 1
                isNew = false;
                Headers tempHeaders = new Headers();
                for (int hierCount = 0; hierCount <  axisInfo.Hierarchies.Count - 1; hierCount++)
                {
                    Header hdr = new Header();
                    hdr.Caption =  axis.Positions[position].Members[hierCount].Caption;
                    if (!hdr.Caption.Equals(previousNewHeaders[hierCount].Caption))
                    {
                        isNew = true;
                        hdr.IsNew = true;
                    }
                    tempHeaders.Add(hdr);
                }

                // Step 2
                Header lastHeader = new Header();
                lastHeader.Caption =  axis.Positions[position].Members[ axisInfo.Hierarchies.Count - 1].Caption;
                lastHeader.IsNew = true;
                tempHeaders.Add(lastHeader);

                // Step 3
                if (isNew)
                {
                     dict.Add(position, tempHeaders);
                    previousNewHeaders = tempHeaders;
                }
            }


            return  dict;
        }

        #endregion


    }
}
